#include "main.h"

PRCondVar* PR_NewCondVar(PRLock *lock);


PRCondVar *consolecond;
PRLock *consolelock;
char **consolebuf;
char **consolebuf_ptr;
int consolebuf_size;



void consoleproc(void *arg) {
	char **x;
	
	while (1) {
		PR_Lock(consolelock); 
		PR_WaitCondVar(consolecond, 200);
		if (consolebuf_ptr > consolebuf) {
			for(x = consolebuf; x < consolebuf_ptr; ++x)
				fprintf(stderr, "%s\n", *x);
			consolebuf_ptr = consolebuf;
		}
		//fprintf(stderr, "*");
		PR_Unlock(consolelock); 
	}
}



void init_console() {
	int consolebuf_maxsize = 1000;
	consolebuf = (char **)calloc(sizeof(char *) * consolebuf_maxsize, 1);
	for(int i = 0; i < consolebuf_maxsize; ++i)
		consolebuf[i] = (char *)malloc(1000);
	consolebuf_size = 0;
	consolebuf_ptr = consolebuf;
	consolelock = PR_NewLock();
	consolecond = PR_NewCondVar(consolelock);
	PR_CreateThread(PR_USER_THREAD, consoleproc, NULL, PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,  PR_JOINABLE_THREAD, 0);
}




/**
 *
 */
void fatal(const char *fmt, ...){
    fprintf(stderr, "FATAL: ");
    va_list args;
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    fprintf(stderr, "\n");
    if (errno)
	    fprintf(stderr, "   last errno=%i (%s)\n", errno, strerror(errno));

#ifdef WITH_EXECINFO
	fprintf(stderr, "\n===========================================\n");
	void * array[25];
	int nSize = backtrace(array, 25);
	char ** symbols = backtrace_symbols(array, nSize);
	for (int i = 0; i < nSize; i++)
		puts(symbols[i]);
	free(symbols);
	fprintf(stderr, "===========================================\n");
#endif
	exit(1);
}



/**
 *
 */
void __trace_printf(char *channel, const char *_fmt, ...){
	static PRLock *lock = NULL;
	if (!lock) lock = PR_NewLock();
	
	char *fmt = (char *)_fmt;
	if (!*_fmt) return;
	if(channel) {
		fmt = (char *)malloc(sizeof(char) * 1024);
		fmt[0] = 0;
		sprintf((char *)fmt, "%s: %s", channel, _fmt);
	}
    va_list args;
    va_start(args, _fmt);    
#ifdef WITH_SYSLOG
	static int syslog_initialized = -1;
	if(syslog_initialized < 0) {
		openlog(PROGRAM_SHORT_NAME, LOG_PERROR | LOG_PID, LOG_USER | LOG_LOCAL0);
		setlogmask(LOG_UPTO(LOG_INFO));
		syslog_initialized = 1;
	}
	vsyslog(LOG_INFO, fmt, args);
#else
	console_set_lock(1);
	vfprintf(stderr, fmt, args);
	fprintf(stderr, "\n");
	console_set_lock(0);
	//vsprintf(*(consolebuf_ptr++), fmt, args);
	
	//PR_NotifyCondVar(consolecond);
#endif
	va_end(args);
}

